#include <queue>
#include "Log.hpp"
#include "Message.hpp"

#define MAX_CAPACI 1024
class MsgPool{
  public:
    MsgPool(size_t size = MAX_CAPACI)
    :max_msg(size){
        pthread_mutex_init(&msg_lock, nullptr);
        pthread_cond_init(&pro_cond, nullptr);
        pthread_cond_init(&con_cond, nullptr);
    }

    ~MsgPool(){
      pthread_mutex_destroy(&msg_lock);
      pthread_cond_destroy(&pro_cond);
      pthread_cond_destroy(&con_cond);
    }

    void PushMsg(std::string& msg){
      pthread_mutex_lock(&msg_lock);
      while(IsFull()){
        pthread_cond_wait(&pro_cond, &msg_lock);
      }
      msg_queue.push(msg);
      pthread_mutex_unlock(&msg_lock);
      pthread_cond_signal(&con_cond);
    }

    void PopMsg(std::string& msg){
      pthread_mutex_lock(&msg_lock);
      while(msg_queue.empty()){
        pthread_cond_wait(&con_cond, &msg_lock);
      }
      msg = msg_queue.front();
      msg_queue.pop();
      pthread_mutex_unlock(&msg_lock);
      pthread_cond_signal(&pro_cond);
    }

  private:
    bool IsFull(){
      return msg_queue.size() == max_msg;
    }

    std::queue<std::string> msg_queue;
    size_t max_msg;
    pthread_mutex_t msg_lock;
    pthread_cond_t pro_cond;
    pthread_cond_t con_cond;
};
